/*
 * @Description: 
 * @Version: 1.0
 * @Autor: ziwei
 * @Date: 2021-05-16 09:36:07
 * @LastEditors: ziwei
 * @LastEditTime: 2021-06-30 10:26:31
 */
export function isFunction(val) {
    return typeof val == 'function'
}

export function isObject(val) {
    return typeof val =='object' && val!=null;
}

let callbacks = [];
let waiting = false;
function flushCallbacks(params) {
  callbacks.forEach(fn=>fn());//按照顺序清空nextTick
  callbacks = [];
  waiting = false;
}

export function nextTick(fn) {//vue3里面的nextTick就是promise vue2做了一些兼容性处理
  callbcks.push(fn);
  if(!waiting){
    Promise.resolve().then(flushCallbacks)
    waiting = true
  }
}

export let isArray = Array.isArray;

//{} bedoreCreate
// {}
let strats = {};//存放所有的策略
let lifeCycle = [
  'beforeCreate',
  'created',
  'beforeMount',
  'mounted',
  'beforeUpdate',
  'updated',
  'beforeDestroy',
  'destroyed',
  'activated',
  'deactivated',
  'errorCaptured',
  'serverPrefetch'
];
lifeCycle.forEach(hook => {
  strats[hook] = function (parentVal, childVal) {
    if (childVal) {
      if (parentVal) {
        return parentVal.concat(childVal)
      } else { // 儿子有值 父亲没有值
        if (isArray(childVal)) {
          return childVal
        } else {
          return [childVal]
        }
      }
    } else {
      return parentVal;
    }
  }
});

//组件的合并策略 依次向上查找 先找儿子 再找自己
strats.components = function(parentVal,childVal) {
  //res._proto_ = parentVal
  let res = Object.create(parentVal);// 合并后产生一个新对象 不用原来的
  if(childVal){
    for(let key in childVal){
      res[key] = childVal[key];
    }
  }
  return res
}

//{} {beforeCreate:fn} => {beforecreate:[fn]}
//
export function mergeOptions(parentVal, childVal) {
  const options = {}
  for (let key in parentVal) {
    mergeFiled(key);
  }
  for (let key in childVal) {
    if (!parentVal.hasOwnProperty(key)) {
      mergeFiled(key);
    }
  }
  function mergeFiled(key) {
    // 设计模式 策略模式
    let strat = strats[key];
    if (strat) {
      options[key] = strat(parentVal[key], childVal[key]); // 合并两个值
    } else {
      options[key] = childVal[key] || parentVal[key];
    }
  }
  return options;
}

export function isSameVnode(){

}

function makeMap(str) {
  let tagList = str.split(',');
  return function (tagName) {
    return tagList.includes(tagName)
  }
}


export const isReservedTag = makeMap(
  'template,script,style,element,content,slot,link,meta,svg,view,button,' +
  'a,div,img,image,text,span,input,switch,textarea,spinner,select,' +
  'slider,slider-neighbor,indicator,canvas,' +
  'list,cell,header,loading,loading-indicator,refresh,scrollable,scroller,' +
  'video,web,embed,tabbar,tabheader,datepicker,timepicker,marquee,countdown'
)

//isReservedTag('div')